package com.moon.game.server;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;
import org.dom4j.Element;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;

import com.moon.game.cache.Memcached;
import com.moon.game.client.UdpClientSet;
import com.moon.game.config.GlobalConfig;
import com.moon.game.constants.Constants;
import com.moon.game.constants.GlobalConstants;
import com.moon.game.exception.GException;
import com.moon.game.proxy.ProxyUtil;
import com.moon.game.resources.DBResource;

public class ProxyServer {

	public static int serverId;
	private static final Logger log = Logger.getLogger(ProxyServer.class);
	private static final String CONFIG_FILE = "config.xml";
	

	// 初始化配置信息
	private static void initConfig() throws Exception {
		GlobalConfig.init(CONFIG_FILE);
	}

	/**
	 * 启动httpServer
	 */
	private static void startHTTPServer(){
		ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
						Executors.newCachedThreadPool(),
						Executors.newCachedThreadPool()));
		bootstrap.setPipelineFactory(new HttpServerPipelineFactory(new HttpServerHandler()));
		Element element = GlobalConfig.getProxyServer(serverId);
		String host = element.attributeValue("host");
		int port = Integer.parseInt(element.attributeValue("http_port"));
		bootstrap.bind(new InetSocketAddress(host, port));
		log.debug("start HttpServer id:" + serverId + ",host:" + host + ",port:" + port);
	}
	
	private static class HttpServerPipelineFactory implements
			ChannelPipelineFactory {
		private SimpleChannelUpstreamHandler handler = null;

		public HttpServerPipelineFactory(SimpleChannelUpstreamHandler handler) {
			this.handler = handler;
		}

		public ChannelPipeline getPipeline() throws Exception {
			ChannelPipeline pipeline = Channels.pipeline();
			pipeline.addLast("decoder", new HttpRequestDecoder());
			pipeline.addLast("encoder", new HttpResponseEncoder());
			pipeline.addLast("handler", handler);
			return pipeline;
		}
	}
	
	private static void initProxy() {
		try {
			ProxyUtil.initFreemaker();
		} catch (GException e) {
			log.error(e.getMessage(), e);
		}
	}
	
	
	/**
	 * 启动服务
	 */
	private static void startServers() {
		log.debug("start httpServer start");
		startHTTPServer();
		log.debug("start httpServer succ！");
	}
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		if (args.length < 1) {
			log.error("please set server id!");
			System.exit(0);
		}
		try {
			serverId = Integer.parseInt(args[0]);
			log.debug("start appserver： " + serverId);
			
			// 初始化配置
			log.debug("init config start...");
			initConfig();
			log.debug("init config end...");
			
			// 初始化memcached
			log.debug("start memcached start...");
			Memcached.initPool(GlobalConstants.POOL_NAME_SYS, Constants.PROXY_MEMCACH_CONNECT_SIZE);
			Memcached.initPool(GlobalConstants.POOL_NAME_CHAT, Constants.PROXY_MEMCACH_CONNECT_SIZE);
			log.debug("start memcached end...");
			
			log.debug("init resource start...");
			DBResource.initResource();
			log.debug("init resource end...");
			
			// 启动Server
			log.debug("start servers start...");
			startServers();
			log.debug("start servers end...");
			
			// 加载页面模版
			log.debug("start templates start...");
			ProxyUtil.loadTemplates(Constants.REGEX_FILE);
			log.debug("start templates end...");
			
			//启动session检查器
			new CheckSessionTask().start();
			
			UdpClientSet.init();
			
			//初始化界面
			log.debug("start proxy start...");
			initProxy();
			log.debug("start proxy end...");
		} catch (Exception e) {
			log.error("App server start error.", e);
			System.exit(0);
		}
		long end = System.currentTimeMillis();
		log.debug("start appserver succ ,use:" + (end - start) + "ms");
	}
}
